package cn.gov.pbc.dream.service.impl;

import java.math.BigDecimal;
import java.util.Date;

import cn.gov.pbc.dream.common.BankFinancingMessageConst;
import cn.gov.pbc.dream.common.ServerResponse;
import cn.gov.pbc.dream.dao.*;
import cn.gov.pbc.dream.pojo.bo.*;
import cn.gov.pbc.dream.pojo.repository.*;
import cn.gov.pbc.dream.service.IAreaService;
import lombok.extern.slf4j.Slf4j;
import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.model.FileHeader;
import org.apache.commons.lang3.StringUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.*;

@Slf4j
public class BankFinancingMessageResolveThread implements Runnable {

    private Map<String, BankFinancingMessageInfoBo> uploadFileMap;

    private BankFinancingMessageResolveStatusBo statusBo;

    private List<PPIMessageBo> ppiMessageBoList = new ArrayList<>();

    private List<PCDMessageBo> pcdMessageBoList = new ArrayList<>();

    private BankFinancingOrgDoMapper bankFinancingOrgDoMapper;

    private AssetPoolDoMapper assetPoolDoMapper;

    private BankFinancingProductInfoDoMapper bankFinancingProductInfoDoMapper;

    private BankFinancingProductCurrencyDoMapper bankFinancingProductCurrencyDoMapper;

    private BankFinancingProductCustomerDoMapper bankFinancingProductCustomerDoMapper;

    private BankFinancingProductIncreaseCreditDoMapper bankFinancingProductIncreaseCreditDoMapper;

    private BankFinancingProductIncreaseMethodDoMapper bankFinancingProductIncreaseMethodDoMapper;

    private BankFinancingProductRaiseInfoDoMapper bankFinancingProductRaiseInfoDoMapper;

    private BankFinancingProductTerminationInfoDoMapper bankFinancingProductTerminationInfoDoMapper;

    private BankFinancingProductFundInfoDoMapper bankFinancingProductFundInfoDoMapper;

    private IAreaService iAreaService;

    public BankFinancingMessageResolveThread(Map<String, BankFinancingMessageInfoBo> uploadFileMap,
                                             BankFinancingMessageResolveStatusBo statusBo,
                                             IAreaService iAreaService,
                                             BankFinancingOrgDoMapper bankFinancingOrgDoMapper,
                                             AssetPoolDoMapper assetPoolDoMapper,
                                             BankFinancingProductInfoDoMapper bankFinancingProductInfoDoMapper,
                                             BankFinancingProductCurrencyDoMapper bankFinancingProductCurrencyDoMapper,
                                             BankFinancingProductCustomerDoMapper bankFinancingProductCustomerDoMapper,
                                             BankFinancingProductIncreaseCreditDoMapper bankFinancingProductIncreaseCreditDoMapper,
                                             BankFinancingProductIncreaseMethodDoMapper bankFinancingProductIncreaseMethodDoMapper,
                                             BankFinancingProductRaiseInfoDoMapper bankFinancingProductRaiseInfoDoMapper,
                                             BankFinancingProductTerminationInfoDoMapper bankFinancingProductTerminationInfoDoMapper,
                                             BankFinancingProductFundInfoDoMapper bankFinancingProductFundInfoDoMapper) {
        this.uploadFileMap = uploadFileMap;
        this.statusBo = statusBo;
        this.iAreaService = iAreaService;
        this.bankFinancingOrgDoMapper = bankFinancingOrgDoMapper;
        this.assetPoolDoMapper = assetPoolDoMapper;
        this.bankFinancingProductInfoDoMapper = bankFinancingProductInfoDoMapper;
        this.bankFinancingProductCurrencyDoMapper = bankFinancingProductCurrencyDoMapper;
        this.bankFinancingProductCustomerDoMapper = bankFinancingProductCustomerDoMapper;
        this.bankFinancingProductIncreaseCreditDoMapper = bankFinancingProductIncreaseCreditDoMapper;
        this.bankFinancingProductIncreaseMethodDoMapper = bankFinancingProductIncreaseMethodDoMapper;
        this.bankFinancingProductRaiseInfoDoMapper = bankFinancingProductRaiseInfoDoMapper;
        this.bankFinancingProductTerminationInfoDoMapper = bankFinancingProductTerminationInfoDoMapper;
        this.bankFinancingProductFundInfoDoMapper = bankFinancingProductFundInfoDoMapper;
    }

    @Override
    public void run() {
        Map<String, List<BankFinancingMessageInfoBo>> fileMap = this.startResolve();
        this.increaseStep();

        try {
            this.decompression(fileMap);
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.increaseStep();

        try {
            this.analysis();
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.increaseStep();

        try {
            this.writeToDatabase();
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.increaseStep();

        this.finish();
        this.increaseStep();
    }

    private void increaseStep() {
        int step = this.statusBo.getStep();
        this.statusBo.setStep(++step);
    }

    private void setStepDesc(int step, String desc) {
        List<String> stepDescList = this.statusBo.getStepDesc();
        stepDescList.set(step, desc);
    }

    private Map<String, List<BankFinancingMessageInfoBo>> startResolve() {
        int stepBelong = 0;
        int fileNumber = this.uploadFileMap.size();
        this.setStepDesc(stepBelong, String.format("接收到%d个文件", fileNumber));
        //对报文进行分机构处理
        Map<String, List<BankFinancingMessageInfoBo>> fileMap = new HashMap<>();
        for (Map.Entry<String, BankFinancingMessageInfoBo> item : this.uploadFileMap.entrySet()) {
            if (!fileMap.containsKey(item.getValue().getOrgCode())) {
                List<BankFinancingMessageInfoBo> list = new ArrayList<>();
                list.add(item.getValue());
                fileMap.put(item.getValue().getOrgCode(), list);
            } else {
                fileMap.get(item.getValue().getOrgCode()).add(item.getValue());
            }
        }
        this.setStepDesc(stepBelong, "完成预处理");
        return fileMap;
    }

    private void decompression(Map<String, List<BankFinancingMessageInfoBo>> fileMap) throws IOException {
        int stepBelong = 1;
        this.setStepDesc(stepBelong, "读PPI");

        for (Map.Entry<String, List<BankFinancingMessageInfoBo>> item : fileMap.entrySet()) {
            //对上传的文件按照日期进行分组
            Map<Date, List<BankFinancingMessageInfoBo>> groupByDateMap = new HashMap<>();
            for (BankFinancingMessageInfoBo bo : item.getValue()) {
                if (!groupByDateMap.containsKey(bo.getReportDate())) {
                    List<BankFinancingMessageInfoBo> list = new ArrayList<>();
                    list.add(bo);
                    groupByDateMap.put(bo.getReportDate(), list);
                } else {
                    groupByDateMap.get(bo.getReportDate()).add(bo);
                }
            }
            for (Map.Entry<Date, List<BankFinancingMessageInfoBo>> groupDateItem : groupByDateMap.entrySet()) {
                List<BankFinancingMessageInfoBo> boList = groupDateItem.getValue();
                //boList 为同一机构，同一日期的报文,但boList中会存在报文分拆情况，需要对报文进行排序后处理
                boList.sort(Comparator.comparingInt(BankFinancingMessageInfoBo::getSequence));
                //对一个机构、一个日期的报文进行合并，只生成一个MessageBo
                PPIMessageBo ppiMessageBo = new PPIMessageBo();
                this.ppiMessageBoList.add(ppiMessageBo);
                ppiMessageBo.setOrgCode(boList.get(0).getOrgCode());
                ppiMessageBo.setReportDate(boList.get(0).getReportDate());
                System.out.println(ppiMessageBo.getReportDate());

                PCDMessageBo pcdMessageBo = new PCDMessageBo();
                this.pcdMessageBoList.add(pcdMessageBo);
                pcdMessageBo.setOrgCode(boList.get(0).getOrgCode());
                pcdMessageBo.setReportDate(boList.get(0).getReportDate());

                for (BankFinancingMessageInfoBo infoBo : boList) {
                    if (infoBo.getMessageType() == BankFinancingMessageConst.Sign.PPI) {
                        //获取PPI文件中的PPB1的InputStream
                        ZipFile zipFile = new ZipFile(infoBo.getFile());
                        FileHeader fileHeader = zipFile.getFileHeader("PPB1.dat");
                        if (fileHeader.getUncompressedSize() != 0) {
                            ppiMessageBo.addPPB1InputStream(zipFile.getInputStream(fileHeader));
                        }
                        //获取PPI文件中的PIB1的InputStream
                        fileHeader = zipFile.getFileHeader("PIB1.dat");
                        if (fileHeader.getUncompressedSize() != 0) {
                            ppiMessageBo.addPIB1InputStream(zipFile.getInputStream(fileHeader));
                        }
                        //获取PPI文件中的PIB2的InputStream
                        fileHeader = zipFile.getFileHeader("PIB2.dat");
                        if (fileHeader.getUncompressedSize() != 0) {
                            ppiMessageBo.addPIB2InputStream(zipFile.getInputStream(fileHeader));
                        }
                        //获取PPI文件中的PIE1的InputStream
                        fileHeader = zipFile.getFileHeader("PIE1.dat");
                        if (fileHeader.getUncompressedSize() != 0) {
                            ppiMessageBo.addPIE1InputStream(zipFile.getInputStream(fileHeader));
                        }
                        //获取PPI文件中的PPE1的InputStream
                        fileHeader = zipFile.getFileHeader("PPE1.dat");
                        if (fileHeader.getUncompressedSize() != 0) {
                            ppiMessageBo.addPPE1InputStream(zipFile.getInputStream(fileHeader));
                        }
                    } else if (infoBo.getMessageType() == BankFinancingMessageConst.Sign.PCD) {
                        //获取PCD文件中的PCD1的InputStream
                        ZipFile zipFile = new ZipFile(infoBo.getFile());
                        FileHeader fileHeader = zipFile.getFileHeader("PCD1.dat");
                        if (fileHeader.getUncompressedSize() != 0) {
                            pcdMessageBo.addPCD1InputStream(zipFile.getInputStream(fileHeader));
                        }
                    }
                }
            }
        }

        this.setStepDesc(stepBelong, "读PCD");

        this.setStepDesc(stepBelong, "读PVD");

        this.setStepDesc(stepBelong, "完成读取zip文件");
    }

    private void analysis() throws IOException {
        int stepBelong = 2;
        //对所有PPI文件按日期进行排序
        this.ppiMessageBoList.sort(Comparator.comparing(PPIMessageBo::getReportDate));

        for (PPIMessageBo ppiMessageBo : this.ppiMessageBoList) {
            //解析PPB1.dat文件
            PPB1Bo ppb1Bo = ppiMessageBo.getPpb1Bo();
            for (BufferedReader br : ppb1Bo.getBufferedReaderList()) {
                String data;
                while ((data = br.readLine()) != null) {
                    ppiMessageBo.assemblePPB1Bo(data);
                }
                br.close();
            }
            //解析PIB1.dat文件
            PIB1Bo pib1Bo = ppiMessageBo.getPib1Bo();
            for (BufferedReader br : pib1Bo.getBufferedReaderList()) {
                String data;
                while ((data = br.readLine()) != null) {
                    ppiMessageBo.assemblePIB1Bo(data);
                }
                br.close();
            }
            //解析PIB2.dat文件
            PIB2Bo pib2Bo = ppiMessageBo.getPib2Bo();
            for (BufferedReader br : pib2Bo.getBufferedReaderList()) {
                String data;
                while ((data = br.readLine()) != null) {
                    ppiMessageBo.assemblePIB2Bo(data);
                }
                br.close();
            }
            //解析PIE1.dat文件
            PIE1Bo pie1Bo = ppiMessageBo.getPie1Bo();
            for (BufferedReader br : pie1Bo.getBufferedReaderList()) {
                String data;
                while ((data = br.readLine()) != null) {
                    ppiMessageBo.assemblePIE1Bo(data);
                }
                br.close();
            }
            //解析PPE1.dat文件
            PPE1Bo ppe1Bo = ppiMessageBo.getPpe1Bo();
            for (BufferedReader br : ppe1Bo.getBufferedReaderList()) {
                String data;
                while ((data = br.readLine()) != null) {
                    ppiMessageBo.assemblePPE1Bo(data);
                }
                br.close();
            }
        }
        //对所有PCD文件按日期进行排序
        this.pcdMessageBoList.sort(Comparator.comparing(PCDMessageBo::getReportDate));
        for (PCDMessageBo pcdMessageBo : this.pcdMessageBoList) {
            //解析PCD1.dat文件
            PCD1Bo pcd1Bo = pcdMessageBo.getPcd1Bo();
            for (BufferedReader br : pcd1Bo.getBufferedReaderList()) {
                String data;
                while ((data = br.readLine()) != null) {
                    pcdMessageBo.assemblePCD1Bo(data);
                }
                br.close();
            }
        }


        this.setStepDesc(stepBelong, "完成报文分析");
    }

    private void writeToDatabase() throws Exception {
        int stepBelong = 3;
        this.setStepDesc(stepBelong, "PPI写入数据库");
        for (PPIMessageBo ppiMessageBo : this.ppiMessageBoList) {
            List<PPB1Bo.PPBItem> ppb1ItemList = ppiMessageBo.getPpb1Bo().getItemList();
            if (ppb1ItemList.size() > 0) {
                this.assetPoolDoMapper.deleteByReportOrgCodeAndReportTime(ppiMessageBo.getOrgCode(), ppiMessageBo.getReportDate());
            }
            List<PIB1Bo.ProductInfo> productInfoList = ppiMessageBo.getPib1Bo().getProductInfoList();
            if (productInfoList.size() > 0) {
                this.bankFinancingProductInfoDoMapper.deleteByReportOrgCodeAndReportTime(ppiMessageBo.getOrgCode(), ppiMessageBo.getReportDate());
            }
            List<PIB1Bo.ProductCurrency> productCurrencyList = ppiMessageBo.getPib1Bo().getProductCurrencyList();
            if (productCurrencyList.size() > 0) {
                this.bankFinancingProductCurrencyDoMapper.deleteByReportOrgCodeAndReportTime(ppiMessageBo.getOrgCode(), ppiMessageBo.getReportDate());
            }
            List<PIB1Bo.ProductCustomer> productCustomerList = ppiMessageBo.getPib1Bo().getProductCustomerList();
            if (productCustomerList.size() > 0) {
                this.bankFinancingProductCustomerDoMapper.deleteByReportOrgCodeAndReportTime(ppiMessageBo.getOrgCode(), ppiMessageBo.getReportDate());
            }
            List<PIB1Bo.IncreaseCredit> increaseCreditList = ppiMessageBo.getPib1Bo().getIncreaseCreditList();
            if (increaseCreditList.size() > 0) {
                this.bankFinancingProductIncreaseCreditDoMapper.deleteByReportOrgCodeAndReportTime(ppiMessageBo.getOrgCode(), ppiMessageBo.getReportDate());
            }
            List<PIB1Bo.IncreaseMethod> increaseMethodList = ppiMessageBo.getPib1Bo().getIncreaseMethodList();
            if (increaseMethodList.size() > 0) {
                this.bankFinancingProductIncreaseMethodDoMapper.deleteByReportOrgCodeAndReportTime(ppiMessageBo.getOrgCode(), ppiMessageBo.getReportDate());
            }
            List<PIB2Bo.ProductRaiseInfo> productRaiseInfoList = ppiMessageBo.getPib2Bo().getProductRaiseInfoList();
            if (productRaiseInfoList.size() > 0) {
                this.bankFinancingProductRaiseInfoDoMapper.deleteByReportOrgCodeAndReportDate(ppiMessageBo.getOrgCode(), ppiMessageBo.getReportDate());
            }
            List<PIE1Bo.ProductTerminationInfo> productTerminationInfoList = ppiMessageBo.getPie1Bo().getProductTerminationInfoList();
            if (productTerminationInfoList.size() > 0) {
                this.bankFinancingProductTerminationInfoDoMapper.deleteByReportOrgCodeAndReportDate(ppiMessageBo.getOrgCode(), ppiMessageBo.getReportDate());
            }

            for (PPB1Bo.PPBItem item : ppb1ItemList) {
                AssetPoolDo selectPoolDo = this.assetPoolDoMapper.selectByAssetPoolCode(item.getCode());
                if (selectPoolDo != null) {
                    this.assetPoolDoMapper.deleteByPrimaryKey(selectPoolDo.getId());

                }
                AssetPoolDo assetPoolDo = this.assembleAssetPoolDo(item, ppiMessageBo);
                if (assetPoolDo == null) {
                    throw new RuntimeException("写入asset_pool表出错");
                }
                this.assetPoolDoMapper.insertSelective(assetPoolDo);
            }


            for (PIB1Bo.ProductInfo productInfo : productInfoList) {
                BankFinancingProductInfoDo selectRow = this.bankFinancingProductInfoDoMapper.selectByCode(productInfo.getCode());
                if (selectRow != null) {
                    this.bankFinancingProductInfoDoMapper.deleteByPrimaryKey(selectRow.getId());
                    this.bankFinancingProductCurrencyDoMapper.deleteByProductCode(selectRow.getCode());
                    this.bankFinancingProductCustomerDoMapper.deleteByProductCode(selectRow.getCode());
                    this.bankFinancingProductIncreaseCreditDoMapper.deleteByProductCode(selectRow.getCode());
                    this.bankFinancingProductIncreaseMethodDoMapper.deleteByProductCode(selectRow.getCode());
                    this.bankFinancingProductRaiseInfoDoMapper.deleteByProductCode(selectRow.getCode());
                    this.bankFinancingProductTerminationInfoDoMapper.deleteByProductCode(selectRow.getCode());
                }
                BankFinancingProductInfoDo infoDo = this.assembleProductInfoDo(productInfo, ppiMessageBo);
                if (infoDo == null) {
                    throw new RuntimeException("写入bank_financing_product_info表出错");
                }
                this.bankFinancingProductInfoDoMapper.insertSelective(infoDo);
            }

            for (PIB1Bo.ProductCurrency currency : productCurrencyList) {
                BankFinancingProductCurrencyDo currencyDo = this.assembleProductCurrencyDo(currency, ppiMessageBo);
                this.bankFinancingProductCurrencyDoMapper.insertSelective(currencyDo);
            }

            for (PIB1Bo.ProductCustomer productCustomer : productCustomerList) {
                BankFinancingProductCustomerDo customerDo = this.assembleProductCustomerDo(productCustomer,
                        ppiMessageBo);
                this.bankFinancingProductCustomerDoMapper.insertSelective(customerDo);
            }

            for (PIB1Bo.IncreaseCredit increaseCredit : increaseCreditList) {
                BankFinancingProductIncreaseCreditDo increaseCreditDo = this.assembleProductIncreaseCreditDo(increaseCredit, ppiMessageBo);
                this.bankFinancingProductIncreaseCreditDoMapper.insertSelective(increaseCreditDo);
            }

            for (PIB1Bo.IncreaseMethod increaseMethod : increaseMethodList) {
                BankFinancingProductIncreaseMethodDo increaseMethodDo = this.assembleProductIncreaseMethodDo(increaseMethod, ppiMessageBo);
                this.bankFinancingProductIncreaseMethodDoMapper.insertSelective(increaseMethodDo);
            }

            for (PIB2Bo.ProductRaiseInfo raiseInfo : productRaiseInfoList) {
                BankFinancingProductRaiseInfoDo raiseInfoDo = this.assembleProductRaiseInfoDo(raiseInfo, ppiMessageBo);
                this.bankFinancingProductRaiseInfoDoMapper.insertSelective(raiseInfoDo);
            }

            for (PIE1Bo.ProductTerminationInfo terminationInfo : productTerminationInfoList) {
                BankFinancingProductTerminationInfoDo terminationInfoDo = this.assembleProductTerminationInfoDo(terminationInfo, ppiMessageBo);
                this.bankFinancingProductTerminationInfoDoMapper.insertSelective(terminationInfoDo);
            }

            List<PPE1Bo.AssetPoolTerminationInfo> assetPoolTerminationInfoList = ppiMessageBo.getPpe1Bo().getAssetPoolTerminationInfoList();
            for (PPE1Bo.AssetPoolTerminationInfo assetPoolTerminationInfo : assetPoolTerminationInfoList) {
                AssetPoolDo assetPoolDo = this.assetPoolDoMapper.selectByAssetPoolCode(assetPoolTerminationInfo.getAssetPoolCode());
                if (assetPoolDo == null) {
                    continue;
                }
                AssetPoolDo insertAssetPoolDo = new AssetPoolDo();
                insertAssetPoolDo.setId(assetPoolDo.getId());
                insertAssetPoolDo.setEndTime(assetPoolTerminationInfo.getTerminationDate());
                int insertCount = this.assetPoolDoMapper.updateByPrimaryKeySelective(insertAssetPoolDo);
                if (insertCount == 0) {
                    throw new RuntimeException("修改资产池终止日期出错");
                }
            }
        }

        this.setStepDesc(stepBelong, "PCD写入数据库");
        for (PCDMessageBo pcdMessageBo : this.pcdMessageBoList) {
            List<PCD1Bo.ProductFundInfo> productFundInfoList = pcdMessageBo.getPcd1Bo().getProductFundInfoList();
            if (productFundInfoList.size() > 0) {
                this.bankFinancingProductFundInfoDoMapper.deleteByReportOrgCodeAndReportDate(pcdMessageBo.getOrgCode(), pcdMessageBo.getReportDate());
            }
            List<BankFinancingProductFundInfoDo> insertList = new ArrayList<>();
            for (int i = 0; i < productFundInfoList.size(); i++) {
                PCD1Bo.ProductFundInfo productFundInfo = productFundInfoList.get(i);
                BankFinancingProductFundInfoDo fundInfoDo = this.assembleProductFundInfoDo(productFundInfo, pcdMessageBo);
                insertList.add(fundInfoDo);
                if (insertList.size() == 100) {
                    this.bankFinancingProductFundInfoDoMapper.insertBatch(insertList);
                    insertList.clear();
                }
                this.setStepDesc(stepBelong, String.format("PCD:%d//%d", i + 1, productFundInfoList.size()));
            }
            if (insertList.size() > 0) {
                this.bankFinancingProductFundInfoDoMapper.insertBatch(insertList);
            }


        }
        this.setStepDesc(stepBelong, "完成写数据库");
    }

    private BankFinancingProductFundInfoDo assembleProductFundInfoDo(PCD1Bo.ProductFundInfo item, PCDMessageBo pcdMessageBo) {
        BankFinancingProductFundInfoDo fundInfoDo = new BankFinancingProductFundInfoDo();
        fundInfoDo.setRaiseDate(item.getRaiseDate());
        fundInfoDo.setBankFinancingProductCode(item.getBankFinancingProductCode());
        if (StringUtils.isNotBlank(item.getAreaCode())) {
            ServerResponse response = this.iAreaService.getAndSaveAreaCode(item.getAreaCode());
            if (!response.isSuccess()) {
                throw new RuntimeException(response.getMsg());
            }
            if(response.getData() instanceof DistrictDo){
                DistrictDo districtDo = (DistrictDo) response.getData();
                fundInfoDo.setDistrictId(districtDo.getId());
            } else {
                AbroadDo abroadDo = (AbroadDo) response.getData();
                fundInfoDo.setAbroadId(abroadDo.getId());
            }

        }
        if (item.getCustomerType() != null) {
            fundInfoDo.setCustomerType(item.getCustomerType().getCode());
        }


        fundInfoDo.setCurrencyCode(item.getCurrencyCode());
        fundInfoDo.setCurrentPeriodPurchaseAmount(item.getCurrentPeriodPurchaseAmount());
        fundInfoDo.setCurrentPeriodPurchaseAmountRmb(item.getCurrentPeriodPurchaseAmountRmb());
        fundInfoDo.setCurrentPeriodPurchaseShare(item.getCurrentPeriodPurchaseShare());
        fundInfoDo.setCurrentPeriodCashedAmount(item.getCurrentPeriodCashedAmount());
        fundInfoDo.setCurrentPeriodCashedAmountRmb(item.getCurrentPeriodCashedAmountRmb());
        fundInfoDo.setCurrentPeriodCashedShare(item.getCurrentPeriodCashedShare());
        fundInfoDo.setEndPeriodAmount(item.getEndPeriodAmount());
        fundInfoDo.setEndPeriodAmountRmb(item.getEndPeriodAmountRmb());
        fundInfoDo.setEndPeriodShare(item.getEndPeriodShare());
        fundInfoDo.setNetValueEndPeriod(item.getNetValueEndPeriod());
        fundInfoDo.setNetValueEndPeriodRmb(item.getNetValueEndPeriodRmb());
        fundInfoDo.setNetValueAccumulativeTotalEndPeriod(item.getNetValueAccumulativeTotalEndPeriod());
        fundInfoDo.setNetValueAccumulativeTotalEndPeriodRmb(item.getNetValueAccumulativeTotalEndPeriodRmb());
        fundInfoDo.setOpenEndNonNetHighestRateOfReturn(item.getOpenEndNonNetHighestRateOfReturn());
        fundInfoDo.setOpenEndNonNetLowestRateOfReturn(item.getOpenEndNonNetLowestRateOfReturn());
        fundInfoDo.setReportTime(pcdMessageBo.getReportDate());
        fundInfoDo.setReportOrgCode(pcdMessageBo.getOrgCode());
        return fundInfoDo;
    }

    private BankFinancingProductTerminationInfoDo assembleProductTerminationInfoDo(PIE1Bo.ProductTerminationInfo item, PPIMessageBo ppiMessageBo) {
        BankFinancingProductTerminationInfoDo terminationInfoDo = new BankFinancingProductTerminationInfoDo();
        terminationInfoDo.setBankFinancingProductCode(item.getBankFinancingProductCode());
        terminationInfoDo.setTerminationDate(item.getTerminationDate());
        terminationInfoDo.setCurrencyCode(item.getCurrencyCode());
        terminationInfoDo.setIncome(item.getIncome());
        terminationInfoDo.setIncomeRmb(item.getIncomeRmb());
        terminationInfoDo.setCustomerIncome(item.getCustomerIncome());
        terminationInfoDo.setCustomerIncomeRmb(item.getCustomerIncomeRmb());
        terminationInfoDo.setCustomerRateOfReturn(item.getCustomerRateOfReturn());
        terminationInfoDo.setReportTime(ppiMessageBo.getReportDate());
        terminationInfoDo.setReportOrgCode(ppiMessageBo.getOrgCode());
        return terminationInfoDo;
    }

    private BankFinancingProductRaiseInfoDo assembleProductRaiseInfoDo(PIB2Bo.ProductRaiseInfo item, PPIMessageBo ppiMessageBo) {
        BankFinancingProductRaiseInfoDo raiseInfoDo = new BankFinancingProductRaiseInfoDo();
        raiseInfoDo.setBankFinancingProductCode(item.getBankFinancingProductCode());
        ServerResponse response = this.iAreaService.getAndSaveAreaCode(item.getAreaCode());
        if (!response.isSuccess()) {
            throw new RuntimeException(response.getMsg());
        }
        if(response.getData() instanceof DistrictDo){
            DistrictDo districtDo = (DistrictDo)response.getData();
            raiseInfoDo.setDistrictId(districtDo.getId());
        } else {
            AbroadDo abroadDo = (AbroadDo)response.getData();
            raiseInfoDo.setAbroadId(abroadDo.getId());
        }
        raiseInfoDo.setCustomerType(item.getCustomerType().getCode());
        raiseInfoDo.setCurrencyCode(item.getCurrencyCode());
        raiseInfoDo.setRaiseAmount(item.getRaiseAmount());
        raiseInfoDo.setRaiseAmountRmb(item.getRaiseAmountRmb());
        raiseInfoDo.setRaiseShares(item.getRaiseShares());
        raiseInfoDo.setReportTime(ppiMessageBo.getReportDate());
        raiseInfoDo.setReportOrgCode(ppiMessageBo.getOrgCode());
        return raiseInfoDo;
    }

    private BankFinancingProductIncreaseMethodDo assembleProductIncreaseMethodDo(PIB1Bo.IncreaseMethod item, PPIMessageBo ppiMessageBo) {
        BankFinancingProductIncreaseMethodDo increaseMethodDo = new BankFinancingProductIncreaseMethodDo();
        increaseMethodDo.setBankFinancingProductCode(item.getBankFinancingProductCode());
        increaseMethodDo.setMethod(item.getIncreaseMethod().getCode());
        increaseMethodDo.setReportTime(ppiMessageBo.getReportDate());
        increaseMethodDo.setReportOrgCode(ppiMessageBo.getOrgCode());
        return increaseMethodDo;
    }

    private BankFinancingProductIncreaseCreditDo assembleProductIncreaseCreditDo(PIB1Bo.IncreaseCredit item, PPIMessageBo ppiMessageBo) {
        BankFinancingProductIncreaseCreditDo increaseCreditDo = new BankFinancingProductIncreaseCreditDo();
        increaseCreditDo.setBankFinancingProductCode(item.getBankFinancingProductCode());
        increaseCreditDo.setType(item.getIncreaseCreditType().getCode());
        increaseCreditDo.setReportTime(ppiMessageBo.getReportDate());
        increaseCreditDo.setReportOrgCode(ppiMessageBo.getOrgCode());
        return increaseCreditDo;
    }

    private BankFinancingProductCustomerDo assembleProductCustomerDo(PIB1Bo.ProductCustomer item, PPIMessageBo ppiMessageBo) {
        BankFinancingProductCustomerDo customerDo = new BankFinancingProductCustomerDo();
        customerDo.setBankFinancingProductCode(item.getBankFinancingProductCode());
        customerDo.setType(item.getCustomerType().getCode());
        customerDo.setReportTime(ppiMessageBo.getReportDate());
        customerDo.setReportOrgCode(ppiMessageBo.getOrgCode());
        return customerDo;
    }

    private BankFinancingProductCurrencyDo assembleProductCurrencyDo(PIB1Bo.ProductCurrency item, PPIMessageBo ppiMessageBo) {
        BankFinancingProductCurrencyDo currencyDo = new BankFinancingProductCurrencyDo();
        currencyDo.setBankFinancingProductCode(item.getBankFinancingProductCode());
        currencyDo.setType(item.getCurrencyType().getCode());
        currencyDo.setCode(item.getCode());
        currencyDo.setReportTime(ppiMessageBo.getReportDate());
        currencyDo.setReportOrgCode(ppiMessageBo.getOrgCode());
        return currencyDo;
    }

    private BankFinancingProductInfoDo assembleProductInfoDo(PIB1Bo.ProductInfo item, PPIMessageBo ppiMessageBo) {
        BankFinancingProductInfoDo infoDo = new BankFinancingProductInfoDo();
        infoDo.setCode(item.getCode());
        if (StringUtils.isNotBlank(item.getBankFinancingOrgCode())) {
            BankFinancingOrgDo orgDo = this.getBankFinancingOrg(item.getBankFinancingOrgCode());
            if (orgDo == null) {
                return null;
            }
            infoDo.setBankFinancingOrgId(orgDo.getId());
        }
        infoDo.setCategory(item.getCategory().getCode());
        infoDo.setName(item.getName());
        infoDo.setBrand(item.getBrand());
        infoDo.setPeriod(item.getPeriod());
        infoDo.setInternalCode(item.getInternalCode());
        infoDo.setCollectionMethod(item.getCollectionMethod().getCode());
        infoDo.setManageMethod(item.getManageMethod().getCode());
        infoDo.setRunMethod(item.getRunMethod().getCode());
        infoDo.setProductType(item.getProductType().getCode());
        infoDo.setBusinessModel(item.getBusinessModel().getCode());
        infoDo.setIncomeProtection(item.getIncomeProtection().getCode());
        infoDo.setPrincipalProtection(item.getPrincipalProtection().getCode());
        infoDo.setHighestRateOfReturn(item.getHighestRateOfReturn());
        infoDo.setLowestRateOfReturn(item.getLowestRateOfReturn());
        infoDo.setRaiseStartDate(item.getRaiseStartDate());
        infoDo.setRaiseEndDate(item.getRaiseEndDate());
        infoDo.setEarlyTerminationRight(item.getEarlyTerminationRight().getCode());
        infoDo.setForeclosures(item.getForeclosures().getCode());
        infoDo.setIncreaseCredit(item.getIncreaseCredit().getCode());
        if (StringUtils.isNotBlank(item.getDomesticCustodyOrg())) {
            BankFinancingOrgDo custodyOrg = this.getBankFinancingOrg(item.getDomesticCustodyOrg());
            if (custodyOrg == null) {
                return null;
            }
            infoDo.setDomesticCustodyOrg(custodyOrg.getId());
        }

        infoDo.setOverseasEscrowCountry(item.getOverseasEscrowCountry());
        infoDo.setOverseasEscrowOrgName(item.getOverseasEscrowOrgName());
        infoDo.setProductStartDate(item.getProductStartDate());
        infoDo.setProductEndDate(item.getProductEndDate());
        infoDo.setAssetPoolCode(item.getAssetPoolCode());
        infoDo.setFiduciaryDuty(item.getFiduciaryDuty().getCode());
        infoDo.setCooperationModal(item.getCooperationModal().getCode());
        if (item.getGrading() != null) {
            infoDo.setGrading(item.getGrading().getCode());
        }
        if (item.getIncomeRightTransfer() != null) {
            infoDo.setIncomeRightTransfer(item.getIncomeRightTransfer().getCode());
        }
        if (item.getSponsorSign() != null) {
            infoDo.setSponsorSign(item.getSponsorSign().getCode());
        }
        infoDo.setReportTime(ppiMessageBo.getReportDate());
        infoDo.setReportOrgCode(ppiMessageBo.getOrgCode());
        return infoDo;
    }

    private BankFinancingOrgDo getBankFinancingOrg(String code) {
        BankFinancingOrgDo orgDo = this.bankFinancingOrgDoMapper.selectByCode(code);
        if (orgDo == null) {
            orgDo = new BankFinancingOrgDo();
            orgDo.setCode(code);
            int insertCount = this.bankFinancingOrgDoMapper.insertSelective(orgDo);
            if (insertCount == 0) {
                return null;
            }
        }
        return orgDo;
    }

    private AssetPoolDo assembleAssetPoolDo(PPB1Bo.PPBItem item, PPIMessageBo messageBo) {
        AssetPoolDo assetPoolDo = new AssetPoolDo();
        assetPoolDo.setCode(item.getCode());

        if (StringUtils.isNotBlank(item.getOrgCode())) {
            BankFinancingOrgDo assetPoolOrg = this.getBankFinancingOrg(item.getOrgCode());
            if (assetPoolOrg == null) {
                return null;
            }
            assetPoolDo.setBankFinancingOrgId(assetPoolOrg.getId());
        }
        assetPoolDo.setName(item.getName());
        assetPoolDo.setStartTime(item.getStartDate());
        assetPoolDo.setReportTime(messageBo.getReportDate());
        assetPoolDo.setReportOrgCode(messageBo.getOrgCode());
        return assetPoolDo;
    }

    private void finish() {
        int stepBelong = 4;
        this.setStepDesc(stepBelong, "报文处理完成");
        this.statusBo.setStatus(BankFinancingMessageConst.Status.FINISH);
    }
}
